package kr.or.javacafe.board.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.support.RequestContextUtils;

import kr.or.common.util.FileUpDownUtil;
import kr.or.common.util.PagingHelper;
import kr.or.common.util.RoleUtil;
import kr.or.common.security.ibatis.*;
import kr.or.javacafe.code.bo.CodeCategoryBO;
import kr.or.javacafe.board.bo.BoardBO;
import kr.or.javacafe.board.domain.Article;
import kr.or.javacafe.board.domain.ArticleFile;
import kr.or.javacafe.board.domain.Bbs;
import kr.or.javacafe.board.domain.Comment;
import kr.or.javacafe.member.domain.User;

@Controller
@RequestMapping("/board")
@SessionAttributes("article")
public class BoardController {

	private static Logger logger = LoggerFactory.getLogger(BoardController.class);

	@Value("#{commonProp['board.paging.row.range']}")
	int m_intRowRange; // 한페이지에 보여줄 레코드 수

	@Value("#{commonProp['board.paging.page.range']}")
	int m_intPageRange; // 페이징한 블럭 갯수

	@Value("#{commonProp['board.article.file.path.server.temp']}")
	String m_strServerUploadPathTemp; 

	@Value("#{commonProp['board.article.file.path.server.real']}")
	String m_strServerUploadPathReal; 

	@Value("#{commonProp['board.article.file.path.local.temp']}")
	String m_strLocalUploadPathTemp; 

	@Value("#{commonProp['board.article.file.path.local.real']}")
	String m_strLocalUploadPathReal; 

	String m_SEPARATOR = System.getProperty("file.separator");

	@Autowired
	CodeCategoryBO codeCategoryBO;
	
	@Autowired
	BoardBO boardBO;

	
	
	
	@RequestMapping(value = "/list/BBS_ID/{bbsId}", method = RequestMethod.GET)
	public String list(@RequestParam(value = "single", required = false, defaultValue = "") String single, String page, @PathVariable String bbsId, HttpServletRequest request, Model model) {
		
		// 게시판 관리 정보
		Bbs objBbsInfo = boardBO.getBbsInfo(bbsId);
		
		// 게시판 권한 정보
		String strRoleRead = "";
		String strRoleWrite = "";		
		User objUserInfo = RoleUtil.getUserInfo();
		if (objUserInfo == null) {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", "G0");
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", "G0");
		} else {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", objUserInfo.getRoleGrpId());
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", objUserInfo.getRoleGrpId());
		}			
		// 목록 조회시 [읽기권한]이 없는 경우 로그인 페이지로 이동시킨다.
		if (strRoleRead == "") throw new UsernameNotFoundException("목록 조회시 접근한 게시판에 Read 권한이 존재하지않습니다.");


		// 게시판 정보
		Article article = new Article();
		article.setBbsId(bbsId);

		// Page 정보
		if (page == null) page = "1";
		if (page.equals("")) page = "1";

		int totalRows = boardBO.getListArticleCount(article);
		int rowRange = m_intRowRange;
		int pageRange = m_intPageRange;
		int pageNum = Integer.parseInt(page);
		String pageURL = "/board/list/BBS_ID/" + bbsId;

		PagingHelper pHelper = PagingHelper.instance;
		pHelper.init(totalRows, rowRange, pageRange, pageNum);

		String pageHTML = pHelper.getPagingHTML(single, pageURL);

		int startNum = pHelper.getStartRownum();
		int endNum = pHelper.getEndRownum();

		
		logger.info("시작 idx : "+startNum);
		logger.info("끝 idx : "+endNum);
		article.setStartBbsThread(startNum);
		article.setEndBbsThread(rowRange);
		List<Article> objArticleList = boardBO.listArticle(article);

		
		logger.info("시작 idx : "+startNum);
		logger.info("끝 idx : "+endNum);
		logger.info("size     :   "+objArticleList.size());
		
		model.addAttribute("boardRoleRead", strRoleRead);
		model.addAttribute("boardRoleWrite", strRoleWrite);
		model.addAttribute("single", single);
		
		model.addAttribute("objBbsInfo", objBbsInfo);
		model.addAttribute("objArticleList", objArticleList);
		model.addAttribute("pageHTML", pageHTML);
		model.addAttribute("page", page);
		
		if (!objBbsInfo.getCdCatId().equals("")) {
			// 게시판 카테고리 정보가 존재할 경우 카테고리 정보를 보여준다.
			model.addAttribute("boardCatgList", codeCategoryBO.listCodeCategoryForCombo(objBbsInfo.getCdCatId()));			
		}
			

		if (objBbsInfo.getBbsTypeCd().equals("FAQ")) 
		{
			// FAQ 타입의 게시판일 경우 관리자만 편집가능
			return "board/faq";
		} 
		else 
		{
			// NTC, QNA 타입의 게시판일 경우
			return "board/list";
		}
	}

	
	@RequestMapping(value = "/view/BBS_ID/{bbsId}/ATC_NO/{atcNo}", method = RequestMethod.GET)
	public String view(@RequestParam(value = "single", required = false, defaultValue = "") String single, String page, @PathVariable String bbsId, @PathVariable String atcNo, HttpServletRequest request, Model model) {
		
		// 게시판 관리 정보
		Bbs objBbsInfo = boardBO.getBbsInfo(bbsId);

		// 게시판 권한 정보
		String strRoleRead = "";
		String strRoleWrite = "";		
		User objUserInfo = RoleUtil.getUserInfo();
		if (objUserInfo == null) {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", "G0");
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", "G0");
		} else {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", objUserInfo.getRoleGrpId());
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", objUserInfo.getRoleGrpId());
		}			
		// 내용 조회시 [읽기권한]이 없는 경우 로그인 페이지로 이동시킨다.
		if (strRoleRead == "") throw new UsernameNotFoundException("내용 조회시 접근한 게시판에 Read 권한이 존재하지않습니다.");


		// 게시판 정보
		Article article = new Article();
		article.setBbsId(bbsId);

		// Page 정보
		if (page == null) page = "1";
		if (page.equals("")) page = "1";
 
		int totalRows = boardBO.getListArticleCount(article);
		int rowRange = m_intRowRange;
		int pageRange = m_intPageRange;
		int pageNum = Integer.parseInt(page);
		String pageURL = "/board/list/BBS_ID/" + bbsId;

		PagingHelper pHelper = PagingHelper.instance;
		pHelper.init(totalRows, rowRange, pageRange, pageNum);

		String pageHTML = pHelper.getPagingHTML(single, pageURL);
		
		int startNum = pHelper.getStartRownum();
		int endNum = pHelper.getEndRownum();

		Article objViewArticle = null;
		Article objNextArticle = null;
		Article objPrevArticle = null;

		article.setStartBbsThread(startNum);
		article.setEndBbsThread(endNum);
		List<Article> objArticleList = boardBO.listArticle(article);
		for (int i = 0; i < objArticleList.size(); i++) {
			if (objArticleList.get(i).getAtcNo() == new Integer(atcNo)) {
				
				objViewArticle = objArticleList.get(i);
				boardBO.hitArticle(new Integer(atcNo));
				
				if (i > 0)
					objNextArticle = objArticleList.get(i - 1);
				
				if (i < (objArticleList.size() - 1))
					objPrevArticle = objArticleList.get(i + 1);
			}
		}


		// 사용자 정보
		String strId = "";
		if (objUserInfo != null) strId = objUserInfo.getId();
		
		// 권한정보
		String strAuth = "";
		if (objUserInfo != null) {
			strAuth = objUserInfo.getRoleGrpId();
		}
		
		model.addAttribute("userRole", strAuth);
		model.addAttribute("boardRoleRead", strRoleRead);
		model.addAttribute("boardRoleWrite", strRoleWrite);
		model.addAttribute("single", single);
		
		model.addAttribute("objBbsInfo", objBbsInfo);
		model.addAttribute("objArticleList", objArticleList);
		model.addAttribute("pageHTML", pageHTML);
		model.addAttribute("page", page);
		model.addAttribute("objViewArticle", objViewArticle);
		model.addAttribute("objNextArticle", objNextArticle);
		model.addAttribute("objPrevArticle", objPrevArticle);
		model.addAttribute("userId", strId);

		if (!objBbsInfo.getCdCatId().equals("")) {
			// 게시판 카테고리 정보가 존재할 경우 카테고리 정보를 보여준다.
			model.addAttribute("boardCatgList", codeCategoryBO.listCodeCategoryForCombo(objBbsInfo.getCdCatId()));			
		}
		
		return "board/view";
	}

	@RequestMapping(value = "/add/BBS_ID/{bbsId}", method = RequestMethod.GET)
	public String add(@RequestParam(value = "single", required = false, defaultValue = "") String single, @RequestParam(value = "atcNo", required = false, defaultValue = "") String atcNo, @PathVariable String bbsId, HttpServletRequest request, Model model) {


		// 게시판 관리 정보
		Bbs objBbsInfo = boardBO.getBbsInfo(bbsId);

		// 게시판 권한 정보
		String strRoleRead = "";
		String strRoleWrite = "";		
		User objUserInfo = RoleUtil.getUserInfo();
		if (objUserInfo == null) {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", "G0");
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", "G0");
		} else {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", objUserInfo.getRoleGrpId());
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", objUserInfo.getRoleGrpId());
		}			
		// 내용 추가시 [쓰기권한]이 없는 경우 로그인 페이지로 이동시킨다.
		if (strRoleWrite == "") throw new UsernameNotFoundException("내용 작성시 접근한 게시판에 Write 권한이 존재하지않습니다.");

		// 사용자 정보
		String strId = "";
		if (objUserInfo != null) strId = objUserInfo.getId();

		Article article = null;
		if (atcNo.equals("")) {
			// 신규 등록
			article = new Article();
			article.setBbsId(bbsId);
			article.setRegrEmpNo(strId);
			article.setRegIp(request.getRemoteAddr());
			article.setModIp(request.getRemoteAddr());
		} else {
			// 답글 등록
			article = boardBO.viewArticle(new Integer(atcNo));
		}

		
		model.addAttribute("userRole", objUserInfo.getRoleGrpId());
		model.addAttribute("boardRoleRead", strRoleRead);
		model.addAttribute("boardRoleWrite", strRoleWrite);
		model.addAttribute("single", single);
		
		model.addAttribute("objBbsInfo", objBbsInfo);
		model.addAttribute("article", article);

		if (!objBbsInfo.getCdCatId().equals("")) {
			// 게시판 카테고리 정보가 존재할 경우 카테고리 정보를 보여준다.
			model.addAttribute("boardCatgList", codeCategoryBO.listCodeCategoryForCombo(objBbsInfo.getCdCatId()));			
		}

		return "board/add";
	}

	@RequestMapping(value = "/add/BBS_ID/{bbsId}", method = RequestMethod.POST)
	public String add(@RequestParam(value = "single", required = false, defaultValue = "") String single, @PathVariable String bbsId, @Valid @ModelAttribute Article article, BindingResult result, SessionStatus status) throws IOException {
		List<ArticleFile> objFileList = new ArrayList<ArticleFile>();

		if (result.hasErrors()) {
			logger.debug("Result Error : " + result.toString());
			return "board/add/BBS_ID/" + bbsId;

		} else {
			String strFilePath;			// TEMP 디렉토리의 파일경로
			String strRealFilePath;		// REAL 디렉토리의 파일경로
			if (System.getProperty("os.name").contains("Windows")) {
				strFilePath = m_strLocalUploadPathTemp + m_SEPARATOR + bbsId;
				strRealFilePath = m_strLocalUploadPathReal + m_SEPARATOR + bbsId;				
			} else {
				strFilePath = m_strServerUploadPathTemp + m_SEPARATOR + bbsId;
				strRealFilePath = m_strServerUploadPathReal + m_SEPARATOR + bbsId;								
			}

			// TEMP 디렉토리의 파일을 REAL 디렉토리로 복사한다. (TEMP 파일은 스케쥴러로 일괄 삭제한다.)
			String fileInfos = article.getFileInfos();
			if (!fileInfos.equals("")) {
				String[] arrTemp = fileInfos.split("<@ROW@>");
				for (String strTempRecord : arrTemp) {
					String[] arrRecord = strTempRecord.split("<@COL@>");

					FileUpDownUtil.fileCopy(strFilePath, strRealFilePath, arrRecord[1]);

					ArticleFile aFile = new ArticleFile();
					aFile.setFileNmReal(arrRecord[0]);
					aFile.setFileNmUpload(arrRecord[1]);
					aFile.setFileSize(new Long(arrRecord[2]));
					aFile.setFilePath(strRealFilePath);
					aFile.setContentType(arrRecord[3]);

					objFileList.add(aFile);
				}
			}

			// DB에 내용을 입력한다.
			boardBO.addArticle(article, objFileList);
		}
		status.setComplete();

		if (single.equals("on"))
			return "redirect:/board/list/BBS_ID/" + bbsId + "?single=on";
		else
			return "redirect:/board/list/BBS_ID/" + bbsId;
	}

	@RequestMapping(value = "/edit/BBS_ID/{bbsId}/ATC_NO/{atcNo}", method = RequestMethod.GET)
	public String edit(@RequestParam(value = "single", required = false, defaultValue = "") String single, @PathVariable String bbsId, @PathVariable String atcNo, HttpServletRequest request, Model model) {

		// 게시판 관리 정보
		Bbs objBbsInfo = boardBO.getBbsInfo(bbsId);
		
		// 게시판 권한 정보
		String strRoleRead = "";
		String strRoleWrite = "";		
		User objUserInfo = RoleUtil.getUserInfo();
		if (objUserInfo == null) {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", "G0");
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", "G0");
		} else {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", objUserInfo.getRoleGrpId());
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", objUserInfo.getRoleGrpId());
		}			
		// 내용 수정시 [쓰기권한]이 없는 경우 로그인 페이지로 이동시킨다.
		if (strRoleWrite == "") throw new UsernameNotFoundException("내용 수정시 접근한 게시판에 Read 권한이 존재하지않습니다.");

		// 게시판 정보
		Article article = boardBO.viewArticle(new Integer(atcNo));
		article.setModIp(request.getRemoteAddr());

		// 사용자 정보
		String strId = "";
		if (objUserInfo != null) strId = objUserInfo.getId();

		model.addAttribute("userRole", objUserInfo.getRoleGrpId());
		model.addAttribute("boardRoleRead", strRoleRead);
		model.addAttribute("boardRoleWrite", strRoleWrite);
		model.addAttribute("single", single);
		
		model.addAttribute("objBbsInfo", objBbsInfo);
		model.addAttribute("article", article);
		model.addAttribute("userId", strId);

		if (!objBbsInfo.getCdCatId().equals("")) {
			// 게시판 카테고리 정보가 존재할 경우 카테고리 정보를 보여준다.
			model.addAttribute("boardCatgList", codeCategoryBO.listCodeCategoryForCombo(objBbsInfo.getCdCatId()));			
		}
		
		return "board/edit";
	}

	@RequestMapping(value = "/edit/BBS_ID/{bbsId}/ATC_NO/{atcNo}", method = RequestMethod.POST)
	public String edit(@RequestParam(value = "single", required = false, defaultValue = "") String single, @PathVariable String bbsId, @PathVariable String atcNo, @Valid @ModelAttribute Article article, BindingResult result, SessionStatus status) throws IOException {
		List<ArticleFile> objFileList = new ArrayList<ArticleFile>();

		if (result.hasErrors()) {
			logger.debug("Result Error : " + result.toString());
			return "board/edit/BBS_ID/" + bbsId + "/ATC_NO/" + atcNo;

		} else {
			String strFilePath;			// TEMP 디렉토리의 파일경로
			String strRealFilePath;		// REAL 디렉토리의 파일경로
			if (System.getProperty("os.name").contains("Windows")) {
				strFilePath = m_strLocalUploadPathTemp + m_SEPARATOR + bbsId;
				strRealFilePath = m_strLocalUploadPathReal + m_SEPARATOR + bbsId;				
			} else {
				strFilePath = m_strServerUploadPathTemp + m_SEPARATOR + bbsId;
				strRealFilePath = m_strServerUploadPathReal + m_SEPARATOR + bbsId;								
			}

			// TEMP 디렉토리의 파일을 REAL 디렉토리로 복사한다. (TEMP 파일은 스케쥴러로 일괄 삭제한다.)
			String fileInfos = article.getFileInfos();
			if (!fileInfos.equals("")) {
				String[] arrTemp = fileInfos.split("<@ROW@>");
				for (String strTempRecord : arrTemp) {
					String[] arrRecord = strTempRecord.split("<@COL@>");

					FileUpDownUtil.fileCopy(strFilePath, strRealFilePath, arrRecord[1]);

					ArticleFile aFile = new ArticleFile();
					aFile.setFileNmReal(arrRecord[0]);
					aFile.setFileNmUpload(arrRecord[1]);
					aFile.setFileSize(new Long(arrRecord[2]));
					aFile.setFilePath(strRealFilePath);
					aFile.setContentType(arrRecord[3]);

					objFileList.add(aFile);
				}
			}

			// DB에 내용을 수정한다.
			boardBO.editArticle(article, objFileList);
		}
		status.setComplete();

		if (single.equals("on"))
			return "redirect:/board/list/BBS_ID/" + bbsId + "?single=on";
		else
			return "redirect:/board/list/BBS_ID/" + bbsId;
	}

	@RequestMapping(value = "/remove/BBS_ID/{bbsId}/ATC_NO/{atcNo}", method = RequestMethod.GET)
	public String remove(@RequestParam(value = "single", required = false, defaultValue = "") String single, @PathVariable String bbsId, @PathVariable String atcNo, Model model) throws IOException {

		// 게시판 관리 정보
		Bbs objBbsInfo = boardBO.getBbsInfo(bbsId);
		
		// 게시판 권한 정보
		String strRoleRead = "";
		String strRoleWrite = "";		
		User objUserInfo = RoleUtil.getUserInfo();
		if (objUserInfo == null) {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", "G0");
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", "G0");
		} else {
			strRoleRead = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "R", objUserInfo.getRoleGrpId());
			strRoleWrite = RoleUtil.getRoleByBoardRead(objBbsInfo.getBbsRole(), "W", objUserInfo.getRoleGrpId());
		}			
		// 내용 삭제시 쓰기권한이 없는 경우 로그인 페이지로 이동시킨다.
		if (strRoleWrite == "") throw new UsernameNotFoundException("내용 삭제시 접근한 게시판에 Read 권한이 존재하지않습니다.");

		// REAL 디렉토리 파일 삭제
		Article article = boardBO.viewArticle(new Integer(atcNo));
		for (ArticleFile articleFile : article.getArticleFileList()) {

			String strRealFilePath;		// REAL 디렉토리의 파일경로
			if (System.getProperty("os.name").contains("Windows")) {
				strRealFilePath = m_strLocalUploadPathReal + m_SEPARATOR + bbsId;				
			} else {
				strRealFilePath = m_strServerUploadPathReal + m_SEPARATOR + bbsId;								
			}

			// REAL 파일을 구해서 삭제
			File objRealFile = new File(strRealFilePath + m_SEPARATOR + articleFile.getFileNmUpload());
			objRealFile.delete();
		}

		// DB 내용 삭제
		Article paramArticle = new Article();
		paramArticle.setAtcNo(new Integer(atcNo));

		ArticleFile paramArticleFile = new ArticleFile();
		paramArticleFile.setAtcNo(new Integer(atcNo));

		boardBO.removeArticle(paramArticle, paramArticleFile);

		if (single.equals("on"))
			return "redirect:/board/list/BBS_ID/" + bbsId + "?single=on";
		else
			return "redirect:/board/list/BBS_ID/" + bbsId;
	}

	
	
	@RequestMapping(value = "/file/download/BBS_ID/{bbsId}/FILE_SEQ/{fileSeq}", method = RequestMethod.GET)
	public void fileDownload(@PathVariable String bbsId, @PathVariable String fileSeq, HttpServletResponse response) throws IOException {
		// 파일 정보를 구한다.
		ArticleFile articleFile = boardBO.getDownloadFile(new Integer(fileSeq));

		String strRealFilePath;		// REAL 디렉토리의 파일경로
		if (System.getProperty("os.name").contains("Windows")) {
			strRealFilePath = m_strLocalUploadPathReal + m_SEPARATOR + bbsId;				
		} else {
			strRealFilePath = m_strServerUploadPathReal + m_SEPARATOR + bbsId;								
		}

		// 다운로드
		FileUpDownUtil.fileDownload(response, strRealFilePath, articleFile.getFileNmUpload(), articleFile.getContentType(), articleFile.getFileNmReal());
	}
	

	@RequestMapping(value = "/file/upload/add/BBS_ID/{bbsId}", method = RequestMethod.POST)
	//@ResponseBody 컴포넌트가 application/json 타입을 지원하지않으므로 text/html 타입으로 json을 리턴한다.
	public void fileUploadAdd(@PathVariable String bbsId, HttpServletRequest request, HttpServletResponse response) throws IOException {

		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;

		MultipartFile mpFile = multipartRequest.getFile("attachFile");

		// 파일 사이즈 체크 (모두 허용 - web 단에서 체크함)		
		// 파일 확장자 체크 (모두 허용 - web 단에서 체크함)
		// 파일의 기초정보 
		String strUniqueFileName = UUID.randomUUID() + "_" + mpFile.getOriginalFilename();
		long lngFileSize = mpFile.getSize();
		String strFileType = mpFile.getContentType();

		String strFilePath;			// TEMP 디렉토리의 파일경로
		if (System.getProperty("os.name").contains("Windows")) {
			strFilePath = m_strLocalUploadPathTemp + m_SEPARATOR + bbsId;
		} else {
			strFilePath = m_strServerUploadPathTemp + m_SEPARATOR + bbsId;
		}		
		
		// 업로드
		int intRet = FileUpDownUtil.fileUpload(lngFileSize, mpFile.getInputStream(), strFilePath, strUniqueFileName);
		
		if (intRet == -1) {
			response.getWriter().append("{success:false, fileSize:" + lngFileSize + "}");
		} else if (intRet == -2) {
			response.getWriter().append("{success:false, fileSize:0}");
		} else {
			response.setContentType("text/html; charset=utf-8");
			response.getWriter().append("{success:true, tempFileName:'" + strUniqueFileName + "', fileSize:" + lngFileSize + ", contentType:'" + strFileType + "'}");			
		}
	}

	
	@RequestMapping(value = "/file/remove/BBS_ID/{bbsId}/ATC_NO/{atcNo}/FILE_SEQ/{fileSeq}", method = RequestMethod.GET)
	public String fileUploadRemove(@RequestParam(value = "single", required = false, defaultValue = "") String single, @PathVariable String bbsId, @PathVariable String atcNo, @PathVariable String fileSeq, HttpServletResponse response) throws IOException {
		// 파일 정보를 구한다.
		ArticleFile articleFile = boardBO.getDownloadFile(new Integer(fileSeq));

		String strRealFilePath;		// REAL 디렉토리의 파일경로
		if (System.getProperty("os.name").contains("Windows")) {
			strRealFilePath = m_strLocalUploadPathReal + m_SEPARATOR + bbsId;				
		} else {
			strRealFilePath = m_strServerUploadPathReal + m_SEPARATOR + bbsId;								
		}

		// REAL 파일을 구해서 삭제
		File objRealFile = new File(strRealFilePath + m_SEPARATOR + articleFile.getFileNmUpload());
		if (objRealFile.delete()) {
			logger.debug("File Remove Error !!!");
		}

		// DB 삭제
		ArticleFile aFile = new ArticleFile();
		aFile.setFileSeq(new Integer(fileSeq));
		boardBO.removeArticleFile(aFile);

		if (single.equals("on"))
			return "redirect:/board/edit/BBS_ID/" + bbsId + "/ATC_NO/" + atcNo + "?single=on";
		else
			return "redirect:/board/edit/BBS_ID/" + bbsId + "/ATC_NO/" + atcNo;	
	}



	@RequestMapping(value = "/comment/list/ATC_NO/{atcNo}", method = RequestMethod.GET)
	@ResponseBody
	public List<Comment> commentList(@PathVariable String atcNo) {
		Comment comment = new Comment();
		comment.setAtcNo(atcNo);

		return boardBO.listComent(comment);
	}

	@RequestMapping(value = "/comment/add/ATC_NO/{atcNo}", method = RequestMethod.POST)
	@ResponseBody
	public String commentAdd(@PathVariable String atcNo, @RequestParam String cmtCont) {
		Comment comment = new Comment();
		comment.setAtcNo(atcNo);
		comment.setCmtCont(cmtCont);

		boardBO.addComment(comment);

		return "SUCCESS";
	}

	@RequestMapping(value = "/comment/remove/ATC_NO/{atcNo}/CMT_SEQ/{cmtSeq}", method = RequestMethod.GET)
	@ResponseBody
	public String commentRemove(@PathVariable String atcNo, @PathVariable int cmtSeq) {
		Comment comment = new Comment();
		comment.setAtcNo(atcNo);
		comment.setCmtSeq(cmtSeq);

		boardBO.removeComment(comment);

		return "SUCCESS";
	}

}